package com.gc.util;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.Properties;
import java.io.IOException;
import java.io.InputStream;
/**
 * 增强型basedao
 * @author gc
 */
public class BaseDao {
    private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>();

    private static String driver = "${driver}";
    private static String url = "${url}";
    private static String username = "${username}";
    private static String pwd = "${pwd}";
    PreparedStatement pstmt = null;

    static {
        Properties prop = new Properties();
        InputStream in = BaseDao.class.getClassLoader().getResourceAsStream("jdbc.properties");
        try {
            prop.load(in);
            driver = prop.getProperty("driver");
            url = prop.getProperty("url");
            username = prop.getProperty("username");
            pwd = prop.getProperty("pwd");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
    * 用户获取数据库连接的，是通过threadlocal来实现单线程共享一个数据裤连接
    * 默认是自动提交事物的
    * @return
    */
    public static Connection getConnection() {
        return getConnection(true);
    }

    /**
    * 如果需要手动提交事物，在调用时传递false来设置手动提交
    * @param flag
    * @return
    */
    public static Connection getConnection(boolean flag) {
        Connection conn = threadLocal.get();
        if(conn==null){
            try {
                Class.forName(driver);
                conn = DriverManager.getConnection(url, username, pwd);
                conn.setAutoCommit(flag);
                threadLocal.set(conn);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return conn;
    }

    /**
    * 通用的用于执行查询的SQL的方法
    * @param sql  查询的SQL
    * @param params  SQL的参数列表，是可变参数（在调用时，按照顺序直接传递即可）
    * @return ResultSet结果集
    */
    public ResultSet executeQuery(String sql,Object... params) {
        Connection conn = getConnection();
        try {
            pstmt = conn.prepareStatement(sql);
            for(int i=0;i<params.length;i++){
                pstmt.setObject((i+1), params[i]);
            }
            return  pstmt.executeQuery();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
    * 通用的执行增删改SQL的方法
    * @param sql  增删改的SQL
    * @param params 参数
    * @return 受影响的行数，如果返回-1，说明执行出错
    */
    public int executeUpdate(String sql,Object... params) {
        Connection conn = getConnection();
        try {
            pstmt = conn.prepareStatement(sql);
            for(int i=0;i<params.length;i++){
                pstmt.setObject((i+1), params[i]);
            }
            return  pstmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return -1;
    }

    /**
    * 关闭连接，释放资源
    */
    public static void closeAll() {
        Connection conn = getConnection();
        if(conn!=null){
            try {
                conn.close();
                threadLocal.set(null);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    /**
    * 提交事务，并关闭连接
    */
    public static void commit(){
        Connection conn = getConnection();
        try {
            conn.commit();
            closeAll();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
